#include "buffer.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "thirdparty/log.h"

static pthread_mutex_t lock_init = PTHREAD_MUTEX_INITIALIZER;

/**
 * 缓存区初始化  缓存区实例需要全部给0
 * buffer   一个缓存区实例
 * length   缓冲区大小
 * return   成功返回0   失败返回-1
 */
int Buffer_Init(Buffer *buffer, int length)
{
    // 判断是否以及初始化过了
    if (buffer->array)
    {
        log_warn("buffer 已经初始化过了...");
        return -1;
    }

    // 分配内存
    buffer->array = malloc(length);
    // 判断内存是否分配成功
    if (!buffer->array)
    {
        // 失败
        log_warn("内存分配失败");
        return -1;
    }

    // 初始化
    buffer->len = 0;
    buffer->read = 0;
    buffer->write = 0;
    buffer->siez = length;
    memcpy(&buffer->lock, &lock_init, sizeof(pthread_mutex_t));

    // 打印日志
    log_trace("buffer %p create %s", buffer, buffer->array);
    return 0;
}

/**
 * 删除缓存区
 * buffer   一个缓存区实例
 * return   成功返回0   失败返回-1
 */
int Buffer_Free(Buffer *buffer)
{
    // 删除缓存区
    if (buffer->array)
    {
        free(buffer->array);
        buffer->array = NULL;
    }
    log_trace("buffer %p delete", buffer);
    return 0;
}

/**
 * 读iffer
 * buffer   一个缓存区实例
 * buf      存储读取数据的容器
 * len      要读多少数据
 * return   成功返回len  失败返回-1
 */
int Buffer_Read(Buffer *buffer, char *buf, int len)
{
    // 判断buffer和buf是否初始化
    if (!buffer || !buf)
    {
        log_warn("buffer or buf not value");
        return -1;
    }

    // 判断长度是否正确
    if (len <= 0)
    {
        log_warn("len not value");
        return -1;
    }

    // 计算实际读取长度
    len = len > buffer->len ? buffer->len : len;

    // 清除buf里面可能残留数据
    // memset(buf, 0, strlen(buf));

    // 读biffer到时候会采用多线程  上锁
    pthread_mutex_lock(&buffer->lock);

    // 判断是需要读两次还是一次
    if (buffer->read + len > buffer->siez)
    {
        // 读两次
        // 计算两次各需要读多少个数据
        int qulen = buffer->siez - buffer->read; // 先读的
        int offlen = len - qulen;
        // 读数据
        memcpy(buf, buffer->array + buffer->read, qulen);
        memcpy(buf + qulen, buffer->array, offlen);
    }
    else
    {
        // 读一次
        memcpy(buf, buffer->array + buffer->read, len);
    }
    // 读下标更新
    buffer->read += len;
    // 判断是否超出最大长度
    if (buffer->read >= buffer->siez)
    {
        buffer->read %= buffer->siez;
    }
    // 数据长度更新
    buffer->len -= len;
    // 释放锁
    pthread_mutex_unlock(&buffer->lock);

    log_trace("buffer = %p buffer->read = %d buffer->len = %d", buffer, buffer->read, buffer->len);
    return len;
}

/**
 * 写buffer
 * buffer   一个缓存区实例
 * buf      存储要写出数据的容器
 * len      要写多少数据
 * return   成功返回0   失败返回-1
 */
int Buffer_Write(Buffer *buffer, char *buf, int len)
{
    // 判断buffer和buf是否初始化
    if (!buffer || !buf)
    {
        log_warn("buffer or buf not value");
        return -1;
    }

    // 判断长度是否正确
    if (len <= 0)
    {
        log_warn("len not value");
        return -1;
    }

    // 判断是否能写的小
    if (buffer->siez - buffer->len < len)
    {
        log_warn("queue length not");
        return -1;
    }

    // 获取锁
    pthread_mutex_lock(&buffer->lock);

    // 计算需要写几次
    if (buffer->write + len > buffer->siez)
    {
        // 写两次
        memcpy(buffer->array + buffer->write, buf, buffer->siez - buffer->write);
        memcpy(buffer->array, buf + buffer->siez - buffer->write, len - (buffer->siez - buffer->write));
    }
    else
    {
        // 写一次
        memcpy(buffer->array + buffer->write, buf, len);
        printf("789%s\n", buf);
    }
    // 写下标更新
    buffer->write += len;
    // 判断是否超出最大长度
    if (buffer->write >= buffer->siez)
    {
        buffer->write %= buffer->siez;
    }
    // 数据长度更新
    buffer->len += len;
    // 释放锁
    pthread_mutex_unlock(&buffer->lock);

    log_trace("buffer = %s buffer->write = %d buffer->len = %d", buffer->array, buffer->write, buffer->len);
    return 0;
}